package com.itcoon.transform.assemble.assembler.inter;

import com.itcoon.transform.base.definition.InjectDefinition;
import com.itcoon.transform.base.exception.AssembleException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

public class MethodAssemblerComposite {

    private static final Logger log = LoggerFactory.getLogger(MethodAssemblerComposite.class);

    @Autowired
    private List<MethodAssembler> methodAssemblers;

    public <T, R> Object assemble(T source, Class<R> targetClass, Object proxy, Method method, List<InjectDefinition.InjectInfo> injectInfos, Object... args) {
        for (MethodAssembler methodAssembler : methodAssemblers) {
            if (methodAssembler.support(targetClass, source, method)) {
                try {
                    return methodAssembler.assemble(source, targetClass, proxy, method, injectInfos, args);
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                    log.error("[Transform4j] - assemble method named #{} failure, it required args is {}, the reason is {}.",method.getName(), Arrays.toString(args), e.getMessage());
                    throw new AssembleException(e.getMessage());
                }
            }
        }
        return null;
    }
}
